package com.nbx.app.neheport.render;

import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import com.nbx.app.neheport.R;
import com.nbx.library.glutes.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class Render09 extends RenderBase {   
    private int mTextureID[];

    private float zoom = -15.0f; // Distance Away From Stars
    private float tilt = 90.0f; // Tilt The View
    private float spin; // Spin Stars
    
    private boolean twinkle = false; // Twinkling Stars

    private float rect[] = { 
           -0.5f, -0.5f,  0.0f,
            0.5f, -0.5f,  0.0f,
           -0.5f,  0.5f,  0.0f,
            0.5f,  0.5f,  0.0f };

    private float tex[] = {
             0.0f, 0.0f,
             1.0f, 0.0f,
             0.0f, 1.0f,
             1.0f, 1.0f,
    };
    
    private class Partical {
        public float r;
        public float g;
        public float b;
        public float dist;
        public float angle;
    };
  
    private final static int num = 50;
    
    Partical star[] = new Partical[num];
   
    private FloatBuffer mCubeVetexBuffer;
    private FloatBuffer mCubeTexBuffer;

    
    public Render09(Context context) {
        super(context);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        mCubeVetexBuffer = util.createFloatBuffer(rect);
        mCubeTexBuffer = util.createFloatBuffer(tex);

        loadBitmapTex(gl);
        
		gl.glEnable(GL10.GL_TEXTURE_2D); // Enable Texture Mapping
		gl.glShadeModel(GL10.GL_SMOOTH); // Enable Smooth Shading
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
		gl.glClearDepthf(1.0f); // Depth Buffer Setup
        gl.glEnable(GL10.GL_DEPTH_TEST); // Enables Depth Testing
        gl.glDepthFunc(GL10.GL_LEQUAL); // The Type Of Depth Testing To Do	
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); // Really Nice Perspective Calculations
		gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE); // Set The Blending Function For Translucency
		gl.glEnable(GL10.GL_BLEND);

        for (int i = 0; i < num; i++) {
            star[i] = new Partical();
            star[i].angle = 0.0f;
            star[i].dist = ( (float)i / num) * 4.0f;
            star[i].r = (float) Math.random();
            star[i].g = (float) Math.random();
            star[i].b = (float) Math.random();
        }
     }
    
    public void onDrawFrame(GL10 gl) {        
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[0]); // Select Our Texture
        
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mCubeVetexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mCubeTexBuffer);

        for (int i = 0; i < num; i++) {
            gl.glLoadIdentity(); // Reset The View Before We Draw Each Star
            gl.glTranslatef(0.0f,0.0f,zoom); // Zoom Into The Screen (Using The Value In 'zoom')
            gl.glRotatef(tilt,1.0f,0.0f,0.0f); // Tilt The View (Using The Value In 'tilt')
            gl.glRotatef(star[i].angle,0.0f,1.0f,0.0f); // Rotate To The Current Stars Angle
            gl.glTranslatef(star[i].dist,0.0f,0.0f); // Move Forward On The X Plane
            gl.glRotatef(-star[i].angle,0.0f,1.0f,0.0f); // Cancel The Current Stars Angle
            gl.glRotatef(-tilt,1.0f,0.0f,0.0f); // Cancel The Screen Tilt
            
            if (twinkle) {
                gl.glColor4f(star[i].r - 0.01f, star[i].g - 0.01f, star[i].b - 0.01f, 1.0f);
                gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
            }

            gl.glRotatef(spin, 0.0f, 0.0f, 1.0f);

            gl.glColor4f(star[i].r, star[i].g, star[i].b, 1.0f);
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

            spin += 0.01f;
            star[i].angle += ((float) i / num);
            star[i].dist -= 0.01f;
            if (star[i].dist < 0.0f) {
                star[i].dist += 4.0f;
                star[i].r = (float) Math.random();
                star[i].g = (float) Math.random();
                star[i].b = (float) Math.random();
            }        
        }
        
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
		gl.glViewport(0, 0, width, height); // Reset The Current Viewport

		gl.glMatrixMode(GL10.GL_PROJECTION); // Select The Projection Matrix
		gl.glLoadIdentity(); // Reset The Projection Matrix

		// Calculate The Aspect Ratio Of The Window
		GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,100.0f);

		gl.glMatrixMode(GL10.GL_MODELVIEW); // Select The Modelview Matrix
		gl.glLoadIdentity();
    }
    
    private void loadBitmapTex(GL10 gl){
        mTextureID = new int[1];
        gl.glGenTextures(1, mTextureID, 0);

        Bitmap bmp = util.getTextureFromBitmapResource(mContext, R.drawable.star);

        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[0]);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
        
        bmp.recycle();

        return;
    }
    
    @Override
    public boolean handleTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {

            return true;
        }
        return false;
    }

    @Override
    public boolean handleKeyEvent(int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_UP) {

        }
        return false;
    }
}
